﻿using YDT_OrderService.Domains.Enums;

namespace YDT_OrderService.Domains.Entities
{
    public class Order : Entity, IAggregateRoot
    {
        public string OrderType { get; private set; }
        public Guid UserId { get; private set; }
        public string OrderSn { get; private set; }
        public decimal OrderTotalPrice { get; private set; }
        public DateTime CreateTime { get; private set; }
        public DateTime UpdateTime { get; private set; }
        public DateTime? PayTime { get; private set; }
        public DateTime? SendTime { get; private set; }
        public DateTime? SuccessTime { get; private set; }
        public OrderStatus OrderStatus { get; private set; }
        public string OrderName { get; private set; }
        public string OrderTel { get; private set; }
        public string OrderAddress { get; private set; }
        public string OrderRemark { get; private set; }

        private readonly List<OrderItem> _orderItems = new();
        public IReadOnlyCollection<OrderItem> OrderItems => _orderItems.AsReadOnly();

        protected Order() { }

        public Order(Guid userId, string orderType, string orderSn, string orderName,
                    string orderTel, string orderAddress, string orderRemark = "")
        {
            Id = Guid.NewGuid();
            UserId = userId;
            OrderType = orderType;
            OrderSn = orderSn;
            OrderName = orderName;
            OrderTel = orderTel;
            OrderAddress = orderAddress;
            OrderRemark = orderRemark;
            OrderStatus = OrderStatus.Pending;
            CreateTime = DateTime.UtcNow;
            UpdateTime = DateTime.UtcNow;
            OrderTotalPrice = 0;
        }

        public void AddOrderItem(Guid productId, string productName, string productUrl,
                               decimal itemPrice, int itemCount)
        {
            var orderItem = new OrderItem(OrderSn, productId, productName, productUrl, itemPrice, itemCount);
            _orderItems.Add(orderItem);
            CalculateTotalPrice();
            UpdateTime = DateTime.UtcNow;
        }

        public void RemoveOrderItem(Guid orderItemId)
        {
            var item = _orderItems.FirstOrDefault(x => x.Id == orderItemId);
            if (item != null)
            {
                _orderItems.Remove(item);
                CalculateTotalPrice();
                UpdateTime = DateTime.UtcNow;
            }
        }

        private void CalculateTotalPrice()
        {
            OrderTotalPrice = _orderItems.Sum(x => x.ItemTotalPrice);
        }

        public void MarkAsPaid()
        {
            if (OrderStatus == OrderStatus.Pending)
            {
                OrderStatus = OrderStatus.Paid;
                PayTime = DateTime.UtcNow;
                UpdateTime = DateTime.UtcNow;
            }
        }

        public void MarkAsShipped()
        {
            if (OrderStatus == OrderStatus.Paid)
            {
                OrderStatus = OrderStatus.Shipped;
                SendTime = DateTime.UtcNow;
                UpdateTime = DateTime.UtcNow;
            }
        }

        public void MarkAsCompleted()
        {
            if (OrderStatus == OrderStatus.Shipped)
            {
                OrderStatus = OrderStatus.Completed;
                SuccessTime = DateTime.UtcNow;
                UpdateTime = DateTime.UtcNow;
            }
        }

        public void Cancel()
        {
            if (OrderStatus == OrderStatus.Pending || OrderStatus == OrderStatus.Paid)
            {
                OrderStatus = OrderStatus.Cancelled;
                UpdateTime = DateTime.UtcNow;
            }
        }
    }
}
